package com.demo.webapp.views.freemarker.directive.search;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;

import com.demo.core.dao.base.support.ResultSearchResult;
import com.demo.core.dao.base.support.SearchArgumentSupport;
import com.demo.search.service.BaseXmlQueryService;
import com.demo.search.support.PageResultSupport;
import com.demo.webapp.action.PageAction;
import com.demo.webapp.views.freemarker.directive.core.PageContextDirectiveSupport;

import freemarker.core.Environment;
import freemarker.core.Environment.TemplateDirectiveBodyEx;
import freemarker.ext.beans.BeanModel;
import freemarker.ext.beans.NumberModel;
import freemarker.template.SimpleHash;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;

/**
 * 自定义指令: 全文检索处理
 * <p/>
 * 处理全文检索结果
 * @author ryuu.kk
 *
 */
public class ResultDirective extends PageContextDirectiveSupport {

	/**
	 * 页面模板名
	 */
	private static final String PAGE_NAME = "classpath:/com/demo/webapp/views/freemarker/directive/template/search-result.ftl";
	
	/**
	 * 查询模板名
	 */
	private static final String TEMPLATE_NAME = "article";
	
	/**
	 * 检索服务
	 */
	@Autowired
	private BaseXmlQueryService queryService;
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public void preWriter(Environment env, TemplateDirectiveBodyEx bodyEx,
			TemplateModel[] loopVars, SimpleHash hash, Map params)
			throws IOException, TemplateException {
		
		String templateName = TEMPLATE_NAME;
		// 查询字符串
		String query = "";
		// 获取范围
		String scope = "";
		// 频道路径
		String channelPath = "";
		// 站点ID
		Long siteId;
		// 渲染模板ID(16进制)
		String render = null;
		
		// 关键字高亮
		boolean highlight;
		// 高亮前置标签;
		String colorPreTag;
		// 高亮后置标签;
		String colorPostTag;
		
		String className = "com.demo.cms.model.Article";
		int limit = 0;		

//		OgnlValueStack valueStack = null;		
//		Object obj = hash.get("stack");
//		if (obj != null && obj instanceof BeanModel) {
//			BeanModel model = (BeanModel) obj;
//			Object vs = model.getWrappedObject();
//			if (vs != null && vs instanceof OgnlValueStack) {
//				valueStack = (OgnlValueStack) vs;
//			}
//			page = (PageAction) valueStack.findValue("action", PageAction.class);
//		}
		
		PageAction page = null;
		Object obj = hash.get("action");
		if (obj != null && obj instanceof BeanModel) {
			BeanModel model = (BeanModel) obj;
			Object action = model.getWrappedObject();
			page = (PageAction) action;
		}
		//page = (PageAction) hash.get("action");
		if (page == null) {
			throw new TemplateException("not found PageAction in ResultDirective", env);
		}
		// 获取范围
		scope = getString("scope", params, getDefaultValue("scope"));
		// 频道路径
		channelPath = getString("channelPath", params, getDefaultValue("channelPath"));
		// 站点ID
		siteId = page.getSite().getId();
		// 渲染模板ID
		NumberModel templateIdModel = (NumberModel) hash.get("templateId");
		if (templateIdModel != null) {
			// 获得渲染模板的16进制ID
			Long templateId = templateIdModel.getAsNumber().longValue();
			render = Long.toHexString(templateId);
		}
		// 高亮前置标签;
		colorPreTag = getString("colorPreTag", params, getDefaultValue("colorPreTag"));
		// 高亮后置标签;
		colorPostTag = getString("colorPostTag", params, getDefaultValue("colorPostTag"));
		// 查询关键字
		query = getString("query", params, getDefaultValue("query"));
		// 转换对象类
		className = getString("className", params, getDefaultValue("className"));
		// 关键字高亮
		highlight = getBoolean("highlight", params, Boolean.valueOf(getDefaultValue("highlight")));
		// 获得分页大小
		limit = getInteger("limit", params, Integer.parseInt(getDefaultValue("limit")));
		page.setPageSize(limit);
		
		Map queryMap = new HashMap();
		
		try {
			query = new String(query.trim().getBytes("ISO-8859-1"), "UTF-8");
			params.put("query", query);
		} catch (UnsupportedEncodingException e) {} 
		queryMap.put("siteId", siteId);
		queryMap.put("channelPath", channelPath);
		//params.put("categoryPath", scope);
		
		queryMap.put(scope, query);
		
		//queryMap.put("title", query);
		//queryMap.put("description", query);
		//queryMap.put("content", query);
		
		Class<?> clazz;
		try {
			clazz = Class.forName(className);
		} catch (ClassNotFoundException e) {
			throw new TemplateException(e, env);
		}
		// 获得分页对象
		SearchArgumentSupport args = page.getArgumentSupport();
		
		PageResultSupport<Class<?>> resultSupport = null;
		if (highlight) {
			// 代码高亮 	
			resultSupport = queryService.queryList(templateName, queryMap, clazz, 
					args.getFirstResult(), args.getMaxResults(), 
					new String[]{ colorPreTag }, new String[]{ colorPostTag });
		} else {
			// 正常显示
			resultSupport = queryService.queryList(templateName, queryMap, clazz, 
					args.getFirstResult(), args.getMaxResults());
		}
		
		if (resultSupport == null) {
			//throw new TemplateException("not found result in Query API", env);
			hash.put("warning", "没有找到检索结果.");
		} else {
			List<Class<?>> resultList = new ArrayList<Class<?>>(resultSupport.getResults());
			page.setResultSupport(new ResultSearchResult<Class<?>>(resultSupport.getResults(), resultSupport.getTotalResults()));
			hash.put("resultList", resultList);
		}
		//hash.put("page", page);
		hash.put("render", render);
		hash.put("channelPath", channelPath);
		
		
	}
	
	@SuppressWarnings("rawtypes")
	@Override
	public String getTemplatePath(Map params) {
		String path = "";
		try {
			path = getString("path", params, PAGE_NAME);
		} catch (TemplateModelException e) {}
		return path;
	}
	    
	@Override
	public void afterInvoke(Writer writer) {
		// nothing.
	}
}
